/*
 * Copyright (C) 2004, Velocityme Partnership
 * TaskActions.java
 *
 * Created on 12 September 2004, 01:56
 */

package com.velocityme.www.interfaces.nodeactions;

import com.velocityme.entity.Activity;
import com.velocityme.entity.Node;
import com.velocityme.entity.Task;
import com.velocityme.entity.Time;
import com.velocityme.enums.Permission;
import com.velocityme.session.ActivityLocal;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.NodeLocal;
import com.velocityme.session.SearchLocal;
import com.velocityme.session.TaskLocal;
import com.velocityme.utility.DurationRemaining;
import com.velocityme.www.actionforms.PersonTimeActionForm;
import com.velocityme.www.actionforms.ReassignResponsibilityActionForm;
import com.velocityme.www.actionforms.TaskDependencyIdActionForm;
import com.velocityme.www.dto.BurnDownDTO;
import com.velocityme.www.dto.TaskDependencyDTO;
import com.velocityme.www.dto.TimeDTO;
import com.velocityme.www.interfaces.ShowNodeAction;
import com.velocityme.www.utility.NodeUtil;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author  Robert
 */
public class TaskActions extends NodeActions {

    /** Creates a new instance of TaskActions */
    public TaskActions() {
    }

    public ActionForward reassignResponsibility(ActionMapping mapping,
                                                ActionForm form,
                                                HttpServletRequest request,
                                                HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        ReassignResponsibilityActionForm reassignResponsibilityActionForm = (ReassignResponsibilityActionForm)form;
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (request.getParameter("btnSubmit").equals("OK")) {
            Long[] contactableIds = reassignResponsibilityActionForm.getResponsibleContactableIds();
            String message = reassignResponsibilityActionForm.getMessage();
            File file = new File(reassignResponsibilityActionForm.getFile().getFileName());
            String contentType = reassignResponsibilityActionForm.getFile().getContentType();
            InputStream stream = reassignResponsibilityActionForm.getFile().getInputStream();
            Calendar start = Calendar.getInstance(); start.clear();
            Calendar stop = Calendar.getInstance(); stop.clear();
            lookupTaskBean().reassignResponsibility(key, nodeId, contactableIds, message, file, contentType, stream);
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }

    public ActionForward toggleInterested(ActionMapping mapping,
                                          ActionForm form,
                                          HttpServletRequest request,
                                          HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (request.getParameter("btnSubmit").equals("OK")) {
            lookupTaskBean().toggleInterested(key, nodeId);
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }

    public ActionForward showDefaultTime(ActionMapping mapping,
                                         ActionForm form,
                                         HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        PersonTimeActionForm taskTimeAF = new PersonTimeActionForm();
        taskTimeAF.setNodeId(nodeId);
        Calendar now = Calendar.getInstance();
        now.add(Calendar.DATE, -7);
        taskTimeAF.setDate(now.getTime());
        return showTime(mapping, taskTimeAF, request, response);
    }

    public ActionForward showTime(ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        PersonTimeActionForm taskTimeAF = (PersonTimeActionForm)form;
        Long nodeId = taskTimeAF.getNodeId();
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = lookupNodeBean().findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, "Time");
        Calendar start = Calendar.getInstance();
        start.setTime(taskTimeAF.getDate());
        String btnSubmit = request.getParameter("btnSubmit");
        if (btnSubmit != null) {
            if (btnSubmit.equals("<")) {
                start.add(Calendar.DATE, -1);
            }
            if (btnSubmit.equals(">")) {
                start.add(Calendar.DATE, 1);
            }
        }
        taskTimeAF.setDate(start.getTime());
        Collection timeDTOs = new ArrayList();
        long totalDuration = 0;
        for (Time time: lookupActivityBean().getTimeAfterDate(key, (Activity)node, start.getTime())) {
            Set assignedPermissions = lookupSearchBean().getAssignedPermissions(key, time.getActivity());
            boolean isEditable = assignedPermissions.contains(Permission.TIME_EDIT);
            boolean isDeletable = assignedPermissions.contains(Permission.TIME_DELETE);
            long timeId = time.getId();
            long activityId = time.getActivity().getId();
            String taskName = time.getActivity().toString();
            String personName = time.getPerson().toString();
            String description = time.getDescription();
            String stateName = time.getState().toString();
            Date startTime = time.getStartTime();
            Date stopTime = time.getStopTime();
            long duration = stopTime.getTime() - startTime.getTime();
            totalDuration += duration;
            int remainingDuration_min = time.getRemainingDuration_min();
            timeDTOs.add(new TimeDTO(isEditable, isDeletable, timeId, activityId, taskName, personName, description, stateName, startTime, stopTime, duration, remainingDuration_min));
        }
        session.setAttribute("taskTimeValue", timeDTOs);
        session.setAttribute("taskDuration", new Long(totalDuration));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("taskTimeAF", taskTimeAF);
        return mapping.findForward("ACTION_DISPLAY");
    }

//    public ActionForward showTimeEdit(ActionMapping mapping,
//                                      ActionForm form,
//                                      HttpServletRequest request,
//                                      HttpServletResponse response) throws Exception {
//        HttpSession session = request.getSession();
//        KeySession key = (KeySession)session.getAttribute("sessionKey");
//        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
//        TimeIdActionForm timeIdActionForm = (TimeIdActionForm)form;
//        TimeValue timeValue = cs.getTimeValue(key, new TimePK(new Integer(timeIdActionForm.getTimeId())));
//        session.setAttribute("timeValue", timeValue);
//        TaskValue taskValue = timeValue.getTaskValue();
//        TaskPK taskPK = taskValue.getPrimaryKey();
//        StateValue[] stateValues = cs.getTaskStateValues(key, taskPK);
//        Collection integerStrings = new ArrayList();
//        for (int i = 0; i < stateValues.length; i++)
//            integerStrings.add(new IntegerString(stateValues[i].getStateId(), stateValues[i].toString()));
//        session.setAttribute("statePairs", integerStrings);
//        Collection completeIntegerStrings = new ArrayList();
//        for (int j = 0; j <= 100; j+=5)
//            completeIntegerStrings.add(new IntegerString(new Integer(j), Integer.toString(j)));
//        session.setAttribute("completePairs", completeIntegerStrings);
//        session.setAttribute("years", NodeUtil.getInstance().getYears());
//        session.setAttribute("months", NodeUtil.getInstance().getMonths());
//        session.setAttribute("days", NodeUtil.getInstance().getDays());
//        session.setAttribute("hours", NodeUtil.getInstance().getHours());
//        session.setAttribute("durationDays", NodeUtil.getInstance().getDurationDays());
//        session.setAttribute("durationHours", NodeUtil.getInstance().getDurationHours());
//        session.setAttribute("minutes", NodeUtil.getInstance().getMinutes());
//        // setup default values
//        TimeActionForm timeActionForm = new TimeActionForm();
//        timeActionForm.setTaskId(taskValue.getTaskId().intValue());
//        timeActionForm.setPercentageComplete(taskValue.getPercentageComplete().byteValue());
//        timeActionForm.setDurationTotalMins(timeValue.getRemainingDuration_min());
//        timeActionForm.setStartDate(timeValue.getStartTime());
//        timeActionForm.setStopDate(timeValue.getStopTime());
//        timeActionForm.setStateId(timeValue.getStateValue().getStateId().intValue());
//        session.setAttribute("timeActionForm", timeActionForm);
//        return mapping.findForward("ACTION_TIME_EDIT");
//    }
//
//    public ActionForward quickTime(ActionMapping mapping,
//                                   ActionForm form,
//                                   HttpServletRequest request,
//                                   HttpServletResponse response) throws Exception {
//        HttpSession session = request.getSession();
//        KeySession key = (KeySession)session.getAttribute("sessionKey");
//        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
//        QuickTimeActionForm quickTimeActionForm = (QuickTimeActionForm)form;
//        NodePK nodePK = new NodePK((Integer)session.getAttribute("nodeId"));
//        TaskPK taskPK = new TaskPK(nodePK.getNodeId());
//        cs.taskTimeQuickAdd(key, taskPK, quickTimeActionForm.getHours());
//        request.setAttribute("nodePK", nodePK);
//        return mapping.findForward("ACTION_SUCCESS");
//    }
//
    static public Collection<TaskDependencyDTO> getDependencyDTOs(KeyLocal key,
                                               Set<Permission> assignedPermissions,
                                               Task task,
                                               boolean dependency) {
        Collection<TaskDependencyDTO> DTOs = new ArrayList<TaskDependencyDTO>();
        boolean isThisDeletable = assignedPermissions.contains(Permission.TASK_EDIT_DEPENDENCY);
        if (dependency) {
            for (Task dTask: lookupTaskBean().getDependencyTasks(key, task)) {
                boolean deletable = isThisDeletable && lookupSearchBean().getAssignedPermissions(key, dTask).contains(Permission.TASK_EDIT_DEPENDENCY);
                DTOs.add(new TaskDependencyDTO(deletable, dTask.getId(), task.getId(), dTask.getPathName()));
            }
        }
        else {
            for (Task dTask: lookupTaskBean().getDependantTasks(key, task)) {
                boolean deletable = isThisDeletable && lookupSearchBean().getAssignedPermissions(key, dTask).contains(Permission.TASK_EDIT_DEPENDENCY);
                DTOs.add(new TaskDependencyDTO(deletable, task.getId(), dTask.getId(), dTask.getPathName()));
            }
        }
        return DTOs;
    }

    public ActionForward dependencyDeleteCheck(ActionMapping mapping,
                                               ActionForm form,
                                               HttpServletRequest request,
                                               HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        session.setAttribute("dependencyValue", form);
        return mapping.findForward("ACTION_DEPENDENCY_DELETE");
    }

    public ActionForward dependencyDelete(ActionMapping mapping,
                                          ActionForm form,
                                          HttpServletRequest request,
                                          HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (request.getParameter("btnSubmit").equals("OK")) {
            TaskDependencyIdActionForm tdAF = (TaskDependencyIdActionForm)form;
            lookupTaskBean().removeDependency(key, tdAF.getDependencyId(), tdAF.getDependantId());
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_DEPENDENCY_DELETE_SUCCESS");
    }
//
//    public ActionForward showGantt(ActionMapping mapping,
//                                   ActionForm form,
//                                   HttpServletRequest request,
//                                   HttpServletResponse response) throws Exception {
//        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
//        HttpSession session = request.getSession();
//        KeySession key = (KeySession)session.getAttribute("sessionKey");
//        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
//        NodeValue nodeValue = cs.getNodeValue(key, nodePK);
//        ShowNodeAction.setupTreeDisplay(session, nodeValue, "Gantt");
//        TaskPK taskPK = new TaskPK(nodePK.getNodeId());
//        GanttChartDTO ganttChartDTO = new GanttChartDTO(cs.getTaskValueTree(key, taskPK, 3));
//        session.setAttribute("ganttChartDTO", ganttChartDTO);
//        return mapping.findForward("ACTION_DISPLAY");
//    }
//
    static public Collection<BurnDownDTO> calculateBurnDownDTOs(Map<String,DurationRemaining> durations) {
        Collection<BurnDownDTO> burnDownDTOs = new ArrayList();
        for (Map.Entry<String,DurationRemaining> entry: durations.entrySet()) {
            int duration_min = entry.getValue().getDuration_min();
            int remaining_min = entry.getValue().getRemaining_min();
            burnDownDTOs.add(new BurnDownDTO(entry.getKey(), duration_min, remaining_min));

        }
        return burnDownDTOs;
    }

    static public Integer calculateMax(Collection<BurnDownDTO> burnDownDTOs) {
        int total = 0;
        for (BurnDownDTO bd: burnDownDTOs) {
            total = Math.max(total, bd.getDuration_min() + bd.getRemaining_min());
        }
        return new Integer(total);
    }

    public ActionForward showBurnDown(ActionMapping mapping,
    								  ActionForm form,
    								  HttpServletRequest request,
    								  HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Activity activity = lookupActivityBean().findActivity(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, activity, "BurnDown");
        Map<String,DurationRemaining> durations = lookupNodeBean().searchDurationSum(key, activity, true, true, activity.getStartDate(), new Date(), false);
        Collection burnDownDTOs = calculateBurnDownDTOs(durations);
        session.setAttribute("burnDownValue", burnDownDTOs);
        session.setAttribute("total", calculateMax(burnDownDTOs));
        return mapping.findForward("ACTION_DISPLAY");
    }

    static private TaskLocal lookupTaskBean() {
        try {
            Context c = new InitialContext();
            return (TaskLocal) c.lookup("java:comp/env/TaskBean");
        } catch (NamingException ne) {
            Logger.getLogger(TaskActions.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private SearchLocal lookupSearchBean() {
        try {
            Context c = new InitialContext();
            return (SearchLocal) c.lookup("java:comp/env/SearchBean");
        } catch (NamingException ne) {
            Logger.getLogger(TaskActions.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private NodeLocal lookupNodeBean() {
        try {
            Context c = new InitialContext();
            return (NodeLocal) c.lookup("java:comp/env/NodeBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private ActivityLocal lookupActivityBean() {
        try {
            Context c = new InitialContext();
            return (ActivityLocal) c.lookup("java:comp/env/ActivityBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

}
